.include "record-def.s"
.include "linux.s"

.section .data
file_name:
    .ascii "test.dat\0"
# 存储输入和输出描述符的栈位置
.equ ST_INPUT_DESCRIPTOR, -8
.equ ST_OUTPUT_DESCRIPTOR, -16
record_buffer_ptr:
    .long 0

.section .bss
.lcomm record_buffer, RECORD_SIZE

.section .text
.globl _start
# 主程序
_start:
    mov     %rsp, %rbp

    call    allocate_init

    push    $RECORD_SIZE
    call    allocate
    mov     %rax, record_buffer_ptr


    # 为保存文件描述符分配空间
    sub     $16, %rsp
    # 打开文件
    mov     $SYS_OPEN, %rax
    mov     $file_name, %rbx
    mov     $0, %rcx            # 表示只读打开
    mov     $0666, %rdx
    int     $LINUX_SYSCALL
    # 保存文件描述符
    mov     %rax, ST_INPUT_DESCRIPTOR(%rbp)
    # 即使输出文件描述符是常量，我们也将它保存到本地变量
    movq     $STDOUT, ST_OUTPUT_DESCRIPTOR(%rbp)

record_read_loop:
    push    ST_INPUT_DESCRIPTOR(%rbp)
    push    record_buffer_ptr
    call    read_record
    add     $16, %rsp

    # 返回读取的字节数，如果字节数与我们请求的字节数不同，
    # 说明已经到达文件结束处或出现错误，我们就要退出。
    cmp     $RECORD_SIZE, %rax
    jne     finished_reading

    mov     record_buffer_ptr, %rax
    add     $RECORD_FIRSTNAME, %rax
    push    %rax
    call    count_chars
    add     $8, %rsp

    mov     %rax, %rdx
    mov     ST_OUTPUT_DESCRIPTOR(%rbp), %rbx
    mov     $SYS_WRITE, %rax
    mov     record_buffer_ptr, %rcx
    add     $RECORD_FIRSTNAME, %rcx
    int     $LINUX_SYSCALL

    push    ST_OUTPUT_DESCRIPTOR(%rbp)
    call    write_newline
    add     $8, %rsp

    jmp     record_read_loop

finished_reading:
    push    ST_OUTPUT_DESCRIPTOR(%rbp)
    call    write_newline
    add     $8, %rsp

    push    record_buffer_ptr
    call    deallocate

    mov     $SYS_EXIT, %rax
    mov     $1, %rbx
    int     $LINUX_SYSCALL

